/**
 * vite.config.ts - 自动导入配置
 */
// ----------------------------------------------------------------------------
// 基本
import { resolve } from "path";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
import progress from "vite-plugin-progress";

import { defineConfig, loadEnv, splitVendorChunkPlugin } from "vite";
import type { ConfigEnv, UserConfig } from "vite";
// ----------------------------------------------------------------------------
// 额外
import { createHtmlPlugin } from "vite-plugin-html";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
// import viteCompression from "vite-plugin-compression";
// import vueI18nPlugin from "@intlify/unplugin-vue-i18n/vite"
import { visualizer } from "rollup-plugin-visualizer";
import vueSetupExtend from "vite-plugin-vue-setup-extend-plus";
// ----------------------------------------------------------------------------
// 自定义
// import { getViteEnv } from './archives/theEnv';
// ----------------------------------------------------------------------------
// 自动导入
// 自动导入组件
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";

// 自动导入图标
import Icons from "unplugin-icons/vite";
import IconsResolver from "unplugin-icons/resolver";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
// ----------------------------------------------------------------------------
// cesium
import vitePluginCesium from "vite-plugin-cesium";
// ----------------------------------------------------------------------------
const ROOT = process.cwd();
const SRC = resolve(ROOT, "src");
const OUT = resolve(ROOT, "dist");
const CAC = resolve(ROOT, "cache");
const ENV = resolve(ROOT, "src/env");
const PUB = resolve(ROOT, "src/public");
// ----------------------------------------------------------------------------
// https://vitejs.dev/config/
export default defineConfig((config: ConfigEnv): UserConfig => {
    const env = loadEnv(config.mode, ENV);
    const viteEnv = getViteEnv(env);
    return buildUserConfig(viteEnv);
});

function getViteEnv(envConf: Recordable): ViteEnv {
    const viteEnv: any = {};
    for (const env_key of Object.keys(envConf)) {
        let env_value = envConf[env_key].replace(/\\n/g, "\n");
        env_value = env_value === "true" ? true : env_value === "false" ? false : env_value;

        if (env_key === "VITE_PORT") {
            env_value = Number(env_value);
        }
        if (env_key === "VITE_PROXY") {
            try {
                env_value = JSON.parse(env_value);
            } catch (error) {}
        }
        viteEnv[env_key] = env_value;
    }
    return viteEnv as ViteEnv;
}

const buildUserConfig = (viteEnv: ViteEnv): UserConfig => {
    // 应用 ViteEnv 到 UserConfig
    const userConfig: UserConfig = {
        /** Shared Options */
        appType: "spa", // APP 类型
        root: ROOT, // 项目根目录（index.html 文件所在的位置）
        assetsInclude: ["**/*.gltf"], // 包含的资产
        cacheDir: CAC, // 存储缓存文件的目录
        envDir: ENV, // 环境文件(.env.*)目录
        publicDir: PUB, // 静态资源服务的文件夹, 在构建期间复制到 build.outDir 的根目录

        resolve: {
            // 别名
            alias: {
                ["@"]: SRC,
                ["vue-i18n"]: "vue-i18n/dist/vue-i18n.cjs.js", // 解决i8n警告 ...vue-i18n.esm-bundler.js
            },
            // 导入时想要省略的扩展名列表
            extensions: [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx", ".json"],
        },

        css: {
            // CSS 模块化
            modules: {
                scopeBehaviour: "global",
            },
            // CSS 预处理器的选项
            preprocessorOptions: {
                scss: {
                    // 预编译支持 scss
                    // additionalData: '@import "src/styles/variables.module.scss";',
                    javascriptEnabled: true, // 支持内联 JavaScript
                },
                less: {
                    // 预编译支持less
                    // additionalData: '@import "@/styles/variables.module.less";',
                    javascriptEnabled: true, // 支持内联 JavaScript
                },
            },
            // CSS sourcemaps enabled during dev
            devSourcemap: true,
        },

        /** Server Options */
        server: {
            host: "0.0.0.0", // 项目运行地址，此处代表 localhosto
            port: viteEnv.VITE_PORT, // 项目运行端口 default = 5173 ()
            open: viteEnv.VITE_OPEN, // 运行 npm run dev 时是否自动打开浏览器
            hmr: viteEnv.VITE_HMR, // 是否开启热加载
            strictPort: false, // 设为 true 时若端口已被占用则会直接退出
            https: false, // 启用 TLS + HTTP/2
            cors: true, // 默认启用并允许任何源
            proxy: {}, // 跨域代理配置,期望接收一个 { key: options }
        },

        /** 插件 */
        plugins: [
            vue({}),
            // vite 可以使用 jsx/tsx 语法
            vueJsx({}),
            // 分包
            splitVendorChunkPlugin(),
            // 编译进度条
            progress(),
            // name 可以写在 script 标签上
            vueSetupExtend(),
            // 复制 cesium 静态资源
            vitePluginCesium(),
            // 分析依赖包大小 (visualizer 不能和 progress 一起使用)
            viteEnv.VITE_REPORT &&
                visualizer({
                    filename: "report.json", // default "stats.html"
                    // json: true,
                    template: "raw-data",
                }),
            // html
            createHtmlPlugin({
                inject: {
                    data: {
                        app_title: viteEnv.VITE_APP_TITLE,
                    },
                },
            }),
            // svg-icon ??
            createSvgIconsPlugin({
                iconDirs: [
                    // 指定需要缓存的图标文件夹
                    resolve(SRC, "assets/icons"),
                    resolve(SRC, "assets/svgs"),
                ],
                symbolId: "icon-sfx-[name]", // icon format. default: icon-[dir]-[name]
            }),
            // 自动导入函数
            AutoImport({
                // 自动导入 Vue 相关函数
                imports: ["vue"],
                // 生成样式文件
                dts: "src/autotypes/auto-imports.d.ts",
                resolvers: [
                    // 自动导入 Element Plus 相关函数
                    ElementPlusResolver(),
                    // 自动导入图标组件
                    // IconsResolver({
                    //     prefix: 'Icon',
                    // }),
                ],
            }),
            // 自动导入组件
            Components({
                // imports: ['vue'],
                // 生成样式文件
                dts: "src/autotypes/auto-components.d.ts",
                resolvers: [
                    // 自动导入 Element Plus 组件
                    // ElementPlusResolver(),
                    // 自动注册图标组件
                    // 重点需要注意的是，使用图标要加上前缀。
                    // 从 element - plus 文档复制 icon 的代码是这样的
                    // <el-icon><ArrowRightBold /></el-icon>
                    // 实际上使用的时候，要加上 i-ep- 前缀，并推荐改成短横线命名
                    // <el-icon><i-ep-arrow-right-bold /></el-icon>
                    // IconsResolver({
                    //     prefix: 'i',
                    //     enabledCollections: ['ep'], // element-plus 图标库
                    // }),
                ],
            }),
            // 自动安装图标
            Icons({
                autoInstall: false,
            }),
        ],

        /** Build Options */
        build: {
            outDir: OUT, // 指定输出路径, 默认 dist
            minify: "esbuild", // specify the minifier to use
            assetsDir: "assets", // 指定生成静态资源的存放路径 (相对于 build.outDir)
            cssCodeSplit: true, // 配置 CSS 代码拆分
            sourcemap: false, // 构建后是否生成 source map 文件, default false
            manifest: true, // 构建后将会生成 manifest.json 文件, 默认 false
            copyPublicDir: true, // 在构建阶段将 public 目录中的所有文件复制到 outDir 目录中
            chunkSizeWarningLimit: 1500, // 调整区块大小警告限制 (in kbs).
            rollupOptions: {
                // 自定义底层的 Rollup 打包配置
                output: {
                    chunkFileNames: "assets/js/[name]-[hash].js",
                    entryFileNames: "assets/js/[name]-[hash].js",
                    assetFileNames: "assets/[ext]/[name]-[hash].[ext]",
                    manualChunks: {
                        // cesium: ['cesium1']
                    },
                },
                external: [],
            },
        },

        // 打包去除 console.log && debugger
        esbuild: {
            pure: viteEnv.VITE_DROP_CONSOLE ? ["console.log", "console.trace", "debugger"] : [],
        },
    };

    return userConfig as UserConfig;
};
